//
//  SPOverlayRenderer.m
//  SPMapKit
//
//  Created by zhangbo on 2017/9/8.
//  Copyright © 2017年 zhangbo. All rights reserved.
//

#import "SPOverlayRenderer.h"

@implementation SPOverlayRenderer

-(instancetype) initWithOverlay:(id<SPOverlay>) overlay
{
    if (self = [super init])
    {
        self.overlay = overlay;
        self.fillColor = [UIColor whiteColor];
        self.strokeColor = [UIColor blackColor];
        self.lineCap = kCGLineCapButt;
        self.lineWidth = 2.0;
        self.lineJoin = kCGLineJoinMiter;
        _overlayScreenPointList = [[NSMutableArray alloc] init];
    }
    
    return self;
}

-(void) drawRect:(CGRect)rect context:(CGContextRef)context
{
    
}

-(NSArray*) overlayScreenPointList
{
    return _overlayScreenPointList;
}

@end

@implementation SPSingleLineRender

-(void) drawRect:(CGRect)rect context:(CGContextRef)context
{
    if (self.overlay == nil || self.delegate == nil) {
        return;
    }
    
    if (![self.overlay isKindOfClass:[SPSingleLine class]]) {
        return;
    }
    
    SPSingleLine *overlay = (SPSingleLine*) self.overlay;
    
//    CGMutablePathRef path = CGPathCreateMutable();
    
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetLineCap(context, self.lineCap);
    CGContextSetLineJoin(context, self.lineJoin);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    
    CGPoint p0 = [self.delegate GPSToScreenPosition:overlay.p0];
    CGContextMoveToPoint(context, p0.x, p0.y);
    
    CGPoint p1 = [self.delegate GPSToScreenPosition:overlay.p1];
    CGContextAddLineToPoint(context, p1.x, p1.y);
    
//    CGPoint line[2];
//    line[0] = p0;
//    line[1] = p1;
    
//    CGContextAddLines(context, line, 2);
    
    CGContextStrokePath(context);
}

-(NSArray*) overlayScreenPointList
{
    [_overlayScreenPointList removeAllObjects];
    
    if (![self.overlay isKindOfClass:[SPSingleLine class]]) {
        return _overlayScreenPointList;
    }
    
    SPSingleLine *overlay = (SPSingleLine*) self.overlay;
    
    CGPoint p0 = [self.delegate GPSToScreenPosition:overlay.p0];
    CGPoint p1 = [self.delegate GPSToScreenPosition:overlay.p1];
    
    [_overlayScreenPointList addObject:[NSValue valueWithCGPoint:p0]];
    [_overlayScreenPointList addObject:[NSValue valueWithCGPoint:p1]];
    
    return _overlayScreenPointList;
}

@end

@implementation SPPolyLineRender

-(void) drawRect:(CGRect)rect context:(CGContextRef)context
{
    if (self.overlay == nil || self.delegate == nil) {
        return;
    }
    
    if (![self.overlay isKindOfClass:[SPPolyline class]]) {
        return;
    }
    
    SPPolyline *overlay = (SPPolyline*) self.overlay;
    if ([overlay.gpspointList count] < 2) {
        return;
    }
    
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetLineCap(context, self.lineCap);
    CGContextSetLineJoin(context, self.lineJoin);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    
    NSValue *firstPoint = [overlay.gpspointList firstObject];
    CGPoint gp = [firstPoint CGPointValue];
    CGPoint p = [self.delegate GPSToScreenPosition:CLLocationCoordinate2DMake(gp.x, gp.y)];
    CGContextMoveToPoint(context, p.x, p.y);
    
    for (int i=1; i<[overlay.gpspointList count]; i++) {
        NSValue *value = [overlay.gpspointList objectAtIndex:i];
        gp = [value CGPointValue];
        p = [self.delegate GPSToScreenPosition:CLLocationCoordinate2DMake(gp.x, gp.y)];
        CGContextAddLineToPoint(context, p.x, p.y);
    }
    
    CGContextStrokePath(context);
}

@end

@implementation SPPolygonRender

-(void) drawRect:(CGRect)rect context:(CGContextRef)context
{
    if (self.overlay == nil || self.delegate == nil) {
        return;
    }
    
    if (![self.overlay isMemberOfClass:[SPPolygon class]]) {
        return;
    }
    
    SPPolyline *overlay = (SPPolyline*) self.overlay;
    if ([overlay.gpspointList count] < 2) {
        return;
    }
    
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetLineCap(context, self.lineCap);
    CGContextSetLineJoin(context, self.lineJoin);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
    
    NSValue *firstPoint = [overlay.gpspointList firstObject];
    CGPoint gp = [firstPoint CGPointValue];
    CGPoint p = [self.delegate GPSToScreenPosition:CLLocationCoordinate2DMake(gp.x, gp.y)];
    CGContextMoveToPoint(context, p.x, p.y);
    
    for (int i=1; i<[overlay.gpspointList count]; i++) {
        NSValue *value = [overlay.gpspointList objectAtIndex:i];
        CGPoint point = [value CGPointValue];
        CGPoint tranp = [self.delegate GPSToScreenPosition:CLLocationCoordinate2DMake(point.x, point.y)];
        CGContextAddLineToPoint(context, tranp.x, tranp.y);
    }
    
    CGContextAddLineToPoint(context, p.x, p.y);
    CGContextDrawPath(context, kCGPathFillStroke);
}

@end

@implementation SPCircleRender

-(void) drawRect:(CGRect)rect context:(CGContextRef)context
{
    if (![self.overlay isMemberOfClass:[SPCircle class]]) {
        return;
    }
    
    SPCircle *overlay = (SPCircle*) self.overlay;
    if (overlay.radius < 0.00001) {
        return;
    }
    
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetLineCap(context, self.lineCap);
    CGContextSetLineJoin(context, self.lineJoin);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
    
    CGFloat radius = overlay.radius / [self.delegate GroundResolution:overlay.coordinate.latitude];
    CGPoint p = [self.delegate GPSToScreenPosition:overlay.coordinate];
    CGRect roundrect = CGRectMake(p.x - radius, p.y - radius, 2 * radius, 2 * radius);
    CGContextAddEllipseInRect(context, roundrect);
    
    CGContextDrawPath(context, kCGPathFillStroke);
}

@end
